int print_open_files(char* notUsed)
{
	int i;
	char curFile[MAX_PATH_LENGTH];
	
	printf("\nFile            FD  Mode       Offset     RefCount\n");
	printf("----------------------------------------------------\n");
	for (i = 0; i < NUM_FILE_DESC; i++)
	{
		if (runningProc->files[i] != 0)
		{
			char fileName[EXT2_MAX_FILE_LENGTH];
			base_name(runningProc->files[i]->memInode->name, fileName);
			
			printf("%-15s %-3d ", fileName, i);
			switch(runningProc->files[i]->mode)
			{
				case FILE_READ: { printf("%-10s ", "READ"); } break;
				
				case FILE_WRITE: { printf("%-10s ", "WRITE"); } break;
				
				case FILE_READ_WRITE: { printf("%-10s ", "READ/WRITE"); } break;
				
				case FILE_APPEND: { printf("%-10s ", "APPEND"); } break;
			}
			printf("%-10ld %d\n", runningProc->files[i]->offset, runningProc->files[i]->refCount);
		}
	}
	putchar('\n');
	return 1;
}

int truncate_file(MINODE* mip)
{
	int i;
	EXT2_DISK* diskInfo;
	
	if (get_device_info(mip->location.deviceHandle, &diskInfo) == -1)
		return -1;
	
	for (i = 0; i < 15; i++)
	{
		/* Truncate direct blocks */
		if ((i < NUM_DIRECT_BLOCKS) && (mip->inode.i_block[i] != 0))
		{
			deallocate_block(mip->location.deviceHandle, mip->inode.i_block[i]);
		}
		/* Single indirect */
		else if ((i == 12) && (mip->inode.i_block[i] != 0))
		{
			int j;
			char pointer1[MAX_BLOCK_SIZE], *pnt1 = pointer1;
			if (read_blk(mip->location.deviceHandle, mip->inode.i_block[i], diskInfo->blockSize, pointer1) == -1)
				return -1;
			for (j = 0; (((*((ulong*)pnt1)) != 0) && (j < diskInfo->blockSize)); j += sizeof(ulong))
			{
				deallocate_block(mip->location.deviceHandle, (*((ulong*)pnt1)));
				pnt1 += sizeof(ulong);
			}
			deallocate_block(mip->location.deviceHandle, mip->inode.i_block[i]);
		}
		/* Double indirect */
		else if ((i == 13) && (mip->inode.i_block[i] != 0))
		{
			int j, k;
			char pointer1[MAX_BLOCK_SIZE], *pnt1 = pointer1;
			char pointer2[MAX_BLOCK_SIZE], *pnt2 = pointer2;
			if (read_blk(mip->location.deviceHandle, mip->inode.i_block[i], diskInfo->blockSize, pointer1) == -1)
				return -1;
			for (j = 0; (((*((ulong*)pnt1)) != 0) && (j < diskInfo->blockSize)); j += sizeof(ulong))
			{
				pnt2 = pointer2;
				if (read_blk(mip->location.deviceHandle, (*((ulong*)pnt1)), diskInfo->blockSize, pointer2) == -1)
					return -1;
				for (k = 0; (((*((ulong*)pnt2)) != 0) && (k < diskInfo->blockSize)); k += sizeof(ulong))
				{
					deallocate_block(mip->location.deviceHandle, (*((ulong*)pnt2)));
					pnt2 += sizeof(ulong);
				}
				deallocate_block(mip->location.deviceHandle, (*((ulong*)pnt1)));
				pnt1 += sizeof(ulong);
			}
			deallocate_block(mip->location.deviceHandle, mip->inode.i_block[i]);
		}
		/* Triple indirect */
		else if ((i == 14) && (mip->inode.i_block[i] != 0))
		{
		}
	}
	
	mip->inode.i_size = 0;
	mip->inode.i_blocks = 0;
	mip->dirty = true;
	
	return 1;
}

int check_if_file_open(MINODE* mip)
{
	int i;
	for (i = 0; i < NUM_OPEN_FILE; i++)
		if (openFiles[i].memInode == mip)
			return i;
	return -1;
}

int get_free_file_entry(void)
{
	int i;
	for (i = 0; i < NUM_OPEN_FILE; i++)
		if (openFiles[i].refCount == 0)
			return i;
	return -1;
}

int get_free_process_entry(void)
{
	int i;
	for (i = 0; i < NUM_OPEN_FILE; i++)
		if (runningProc->files[i] == 0)
			return i;
	return -1;
}

int open_file(char* path, int mode)
{
	if ((mode == FILE_READ) || (mode == FILE_WRITE) ||
		(mode == FILE_READ_WRITE) || (mode == FILE_APPEND))
	{
		LOC inodeLoc;
		MINODE* mip = 0;
		
		inodeLoc = get_inode_number(path);
		if (inodeLoc.inodeNum == 0)
		{
			printf("Specified path, \"%s\", does not exist\n\n", path);
			return -1;
		}
			
		mip = get_inode(inodeLoc.deviceHandle, inodeLoc.inodeNum);
		if (mip == 0)
			return -1;
		
		/* Make sure it's a file and not a dir */	
		if (mip->inode.i_mode & IMODE_REGFILE)
		{
			int proc_entry = 0;
			int entry = check_if_file_open(mip);
			
			/* Need to open file */
			if (entry == -1)
			{
				entry = get_free_file_entry();
				if (entry == -1)
				{
					printf("Can't open any more files\n\n");
					put_inode(mip);
					return -1;
				}
				openFiles[entry].mode = mode;
				openFiles[entry].refCount = 0;
				openFiles[entry].memInode = mip;
				if (mode == FILE_WRITE)
					truncate_file(openFiles[entry].memInode);
				if (mode == FILE_APPEND)
					openFiles[entry].offset = mip->inode.i_size;
				else
					openFiles[entry].offset = 0;
			}
			/* Already opened, check mode compatibility */
			else if (((openFiles[entry].mode == FILE_READ) && (mode != FILE_READ)) ||
					 ((openFiles[entry].mode == FILE_WRITE) && (mode != FILE_WRITE)) ||
					 ((openFiles[entry].mode == FILE_READ_WRITE) && (mode != FILE_READ_WRITE)) ||
					 ((openFiles[entry].mode == FILE_APPEND) && (mode != FILE_APPEND)))
			{
				printf("\nCannot open file, already opened with incompatible mode\n");
				put_inode(mip);
				return -1;
			}
			
			if (entry == -1)
				proc_entry = get_free_process_entry();
			else
				proc_entry = entry;
				
			runningProc->files[proc_entry] = &(openFiles[entry]);
			runningProc->files[proc_entry]->refCount++;
			
			if (mode == FILE_READ)
				mip->inode.i_atime = time(0);
			else
				mip->inode.i_mtime = time(0);
			mip->dirty = true;
			
			strcpy(runningProc->files[proc_entry]->memInode->name, path);
			
			return proc_entry;
		}
	}
	return -1;
}

int do_open(char* notUsed)
{
	int mode = 0, returnVal = 0;
	char file[MAX_PATH_LENGTH];
	
	printf("Enter name of file to open: ");
	gets(file);
	
	printf("Choose mode [ READ(1) WRITE(2) RDWR(3) APPEND(4) ]: ");
	scanf("%d", &mode);
	
	switch(mode)
	{
		case 1: { mode = FILE_READ; } break;
		case 2: { mode = FILE_WRITE; } break;
		case 3: { mode = FILE_READ_WRITE; } break;
		case 4: { mode = FILE_APPEND; } break;
	}
	
	if (file[0] != '/')
	{
		char pwd[MAX_PATH_LENGTH];
		get_pwd_name(runningProc->cwd, pwd);
		strcat(pwd, file);
		strcpy(file, pwd);
	}
	
	returnVal = open_file(file, mode);
	
	if (returnVal != -1)
		printf("\nFile opened successfully!\n");
		
	putchar('\n');
	getchar();
		
	return returnVal;
}
